package com.hzit.loan.manager.config;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 1. 创建所有的dataSource EnvironmentAware 初始化环境
 * 2. 创建好的dataSource注册 ImportBeanDefinitionRegistrar
 */
public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    //默认的数据源
    private DataSource defaultDataSource;

    //配置文件中的路径
    private static String DB_DEFAULT_VALUE = "custom.datasource";

    //配置文件中更多的前缀
    private static String DB_NAME = "names";

    //更多的数据源
    private Map<String, DataSource> customDataSources = new HashMap<>();

    //阿里巴巴 durid数据源,c3p0,hikra,durid
    private static final Object DATASOURCE_TYPE_DEFAULT = "com.alibaba.druid.pool.DruidDataSource";


    /**
     * 初始化环境，创建数据源
     * @param environment
     */
    @Override
    public void setEnvironment(Environment environment) {

        //1.初始化默认
        initDefaultDataSource(environment);

        //2.初始化其他的
        initCustomDataSources(environment);

    }

//    @Override
//    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
//
//    }

    /**
     * 将dataSource注入
     * @param importingClassMetadata
     * @param registry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();

        // 将默认数据源添加到更多数据源中
        targetDataSources.put("dataSource", defaultDataSource);

        DynamicDataSourceContextHolder.dataSourceIds.add("dataSource");

        // 添加更多数据源
        targetDataSources.putAll(customDataSources);
        for (String key : customDataSources.keySet()) {
            DynamicDataSourceContextHolder.dataSourceIds.add(key);
        }

        // 创建DynamicDataSource 动态数据源
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(DynamicDataSource.class);
        beanDefinition.setSynthetic(true);
        MutablePropertyValues mpv = beanDefinition.getPropertyValues();
        mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource);
        mpv.addPropertyValue("targetDataSources", targetDataSources);

        registry.registerBeanDefinition("dataSource", beanDefinition);

    }



    //初始化默认数据源
    private void initDefaultDataSource(Environment env) {
        // 读取 application.properties
        Map<String, Object> dsMap = new HashMap<>();
        dsMap.put("type", env.getProperty(DB_DEFAULT_VALUE + "." + "type"));
        dsMap.put("driver-class-name", env.getProperty(DB_DEFAULT_VALUE + "." + "driver-class-name"));
        dsMap.put("url", env.getProperty(DB_DEFAULT_VALUE + "." + "url"));
        dsMap.put("username", env.getProperty(DB_DEFAULT_VALUE + "." + "username"));
        dsMap.put("password", env.getProperty(DB_DEFAULT_VALUE + "." + "password"));
        defaultDataSource = buildDataSource(dsMap);
    }


    // 初始化更多数据源
    private void initCustomDataSources(Environment env) {
        // 读取配置文件获取更多数据源，也可以通过defaultDataSource读取数据库获取更多数据源
//        RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env,DB_DEFAULT_VALUE+".");
        String dsPrefixs = env.getProperty(DB_DEFAULT_VALUE + "." + DB_NAME);

        for (String dsPrefix : dsPrefixs.split(",")) {// 多个数据源
            Map<String, Object> dsMap = new HashMap<>();

            dsMap.put("type", env.getProperty(DB_DEFAULT_VALUE + "." + dsPrefix + ".type"));
            dsMap.put("driver-class-name", env.getProperty(DB_DEFAULT_VALUE + "." + dsPrefix + ".driver-class-name"));
            dsMap.put("url", env.getProperty(DB_DEFAULT_VALUE + "." + dsPrefix + ".url"));
            dsMap.put("username", env.getProperty(DB_DEFAULT_VALUE + "." + dsPrefix + ".username"));
            dsMap.put("password", env.getProperty(DB_DEFAULT_VALUE + "." + dsPrefix + ".password"));


            DataSource ds = buildDataSource(dsMap);
            customDataSources.put(dsPrefix, ds);
        }
    }


    /**
     * 创建dataSource
     * @param dsMap
     * @return
     */
    @SuppressWarnings("unchecked")
    public DataSource buildDataSource(Map<String, Object> dsMap) {
        try {
            Object type = dsMap.get("type");
            if (type == null){
                type = DATASOURCE_TYPE_DEFAULT;// 默认DataSource

            }

            Class<? extends DataSource> dataSourceType;
            dataSourceType = (Class<? extends DataSource>) Class.forName((String) type);

            String driverClassName = dsMap.get("driver-class-name").toString();
            String url = dsMap.get("url").toString();
            String username = dsMap.get("username").toString();
            String password = dsMap.get("password").toString();

            DataSourceBuilder factory = DataSourceBuilder.create().driverClassName(driverClassName).url(url)
                    .username(username).password(password).type(dataSourceType);
            return factory.build();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }





}
